這兩天分享了Spring Security建立方式,UserService以及Spring Security升版之後的用法。
今天廢話不多說,我們就直接切入正題吧 !!!
我們在ApSecurityConfig中,透過InMemoryUserDetailsManager
來實作UserService,建立帳號與密碼並儲存於記憶體中,範例如下,我們建立了兩組帳號與密碼,並且分別給他們對應的角色權限
@Configuration
@EnableWebSecurity
public class ApSecurityConfig {
@Bean
public UserDetailsService userDetailsService() throws Exception {
User.UserBuilder users = User.withDefaultPasswordEncoder();
InMemoryUserDetailsManager manager = new InMemoryUserDetailsManager();
manager.createUser(users.username("user").password("user").roles(String.valueOf(UserRole.USER)).build());
manager.createUser(users.username("admin").password("admin").roles(String.valueOf(UserRole.USER), String.valueOf(UserRole.ADMIN)).build());
return manager;
}
}
接著我們就可以啟動應用程式,並使用以下網址「http://localhost:8080/login」
使用我們剛剛在上面建立的帳密登入看看,這個時候我們會看到成功登入了,但會出現Whitelabel Error Page,這個時候就是在跟我們說要建立下一步驟了。
我們接續著上面建立的ApSecurityConfig,我們繼續建立filterChain來管理API
permitAll()
: 這邊是指不用任何的驗證授權就可以訪問,所以依照我們底下的設定,代表pulic/...都可以直接訪問 @Bean
public SecurityFilterChain apiFilterChain(HttpSecurity http) throws Exception {
http
.authorizeHttpRequests(
requests -> requests
.requestMatchers("/public/**").permitAll()
.requestMatchers("/admin/**").hasRole("ADMIN")
.anyRequest()
.authenticated()
)
.formLogin(withDefaults())
.logout(withDefaults());
return http.build();
}
所以我們來建立對應的controller來等等測試看看
@RestController
@Slf4j
@RequestMapping(name = "/public", consumes = MediaType.APPLICATION_JSON_VALUE,
produces = MediaType.APPLICATION_JSON_VALUE)
public class PublicController {
@Autowired
private BookRepo bookRepo;
@GetMapping("books")
public ResponseEntity<List<Book>> getUserName() {
return ResponseEntity.ok(bookRepo.findAll());
}
}
接著我們就可以啟動應用程式,並使用以下網址「http://localhost:8080/login」,我們等等用兩個帳號登入測試看看是否可以都正常訪問到API
「http://localhost:8080/public/books」
,我們可以得到以下結果hasRole
: 這樣就需要有指定的角色權限才可以訪問API,在我們上面的範例,登入的帳號需要是ADMIN角色才可以使用,那我們就用以下API進行測試 @GetMapping("admin/book/{bookId}")
@Operation(summary = "Gets book by ID", description= "Book must exist")
@ApiResponses(value = {
@ApiResponse(responseCode = "200", description = "Success to find book"),
@ApiResponse(responseCode = "404", description = "Book not found")})
public ResponseEntity<Book> getUserName(@PathVariable("bookId") int bookId) throws NotBoundException, BadRequestException {
Book response = ironService.findBookById(bookId);
if(Objects.isNull(response)) {
return ResponseEntity.notFound().build();
} else {
return ResponseEntity.ok(ironService.findBookById(bookId));
}
}
1.我們先用帳號:user進行登入
2.接著我們就來訪問看看 「http://localhost:8080/admin/book/1」
,我們可以得到以下結果,我們發現沒有權限訪問,所以就直接變成Whitelabel Error Page
3.那我們就用帳號:admin進行登入
4.接著我們就來訪問看看 「http://localhost:8080/admin/book/1」
,我們可以得到以下結果,我們有可以順利訪問API
我們可以透過Spring Security來進行帳號密碼驗證,如果有興趣的大家也可以再研究看看Basic Auth跟JWT的驗證方式,另外我們也可以自訂filterChain來針對介面設定是否需要授權、驗證,讓我們的Application安全性更加升級。